﻿using AutoMapper.Internal.Mappers;
using rbac.contracts.Dto.Output;
using rbac.contracts.Interface;
using rbac.domain.Interface;
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using rbac.contracts.Dto.Input;

namespace rbac.services
{
    public class UserService : IUserService
    {
        private readonly IUserRepository _userRepository;
        private readonly IMapper _objectMapper;
        private readonly IUserRoleRepository _userroleRepository;
        private readonly IRoleRepository _roleRepository;

        public UserService(IUserRepository userRepository
            , IMapper objectMapper, IUserRoleRepository userroleRepository
            , IRoleRepository roleRepository)
        {
            _userRepository = userRepository;
            _objectMapper= objectMapper;
            _userroleRepository = userroleRepository;
            _roleRepository = roleRepository;
        }

        public PageOutput<UserOutput> GetUsers(GetUsersInput input)
        {
            var list = _userRepository.GetUsers();
            if (!string.IsNullOrEmpty(input.UserName))
            {
                //查询"管理%"
                list = list.Where(x => x.UserName!.StartsWith(input.UserName));
            }
            if (!string.IsNullOrEmpty(input.Email))
            {
                //查询“%331@qq.com%”
                list = list.Where(x => x.Email!.Contains(input.Email));
            }
            PageOutput<UserOutput> result = new()
            {
                Total = list.Count(),
                PageSize = input.PageSize
            };
            var lists = list.OrderBy(x => x.Id).Skip((input.PageIndex - 1) * input.PageSize).Take(input.PageSize).ToList();

            var userIdlist = lists.Select(x => x.Id);

            var rolelist= (from ur in _userroleRepository.UserRoles()
            join r in _roleRepository.Roles()
            on ur.RoleId equals r.Id
            where userIdlist.Contains(ur.UserId)
            select new
            {
                ur.UserId,
                r.RoleName,
                r.Id
            }).ToList();

            var roleGroup=rolelist.GroupBy(x => x.UserId).ToList();

            result.Data = _objectMapper.Map<List<UserOutput>>(lists);
            foreach(var g in result.Data)
            {
                foreach(var s in roleGroup)
                {
                    if (g.Id == s.Key)
                    {
                        g.roles = s.ToList().Select(x => new RoleOutput
                        {
                            Id = x.Id,
                            RoleName = x.RoleName,
                        }).ToList();
                    }
                }
            }
            return result;
        }

        public UserOutput Login(LoginInput input)
        {
            var user = _userRepository.Login(input.UserName, input.Pwd);
            var dto=_objectMapper.Map<UserOutput>(user);
            if (dto != null)
            {
                var roles = _userroleRepository.UserRolesBuUserId(user.Id);
                dto.roles = _objectMapper.Map<List<RoleOutput>>(roles);
            }
            return dto;
        }
    }
}
